package edu.uob;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

public class DeleteCondition {

    public static void handleCondition(Table table, String allCondition) {

        String cleanedCondition = allCondition.replaceAll("[()]", "");
        cleanedCondition = cleanedCondition.replaceAll("\\s+", "");
        // 使用正则表达式分割字符串为单个条件
        String[] conditions = cleanedCondition.split("(?=(AND|OR))|(?<=(AND|OR))");
        // 初始化存储 AND 和 OR 操作符的列表
        List<String> operators = new ArrayList<>();
        // 初始化存储条件的列表
        List<String> conditionList = new ArrayList<>();
        List<Condition> parsedConditionList = new ArrayList<>();
        // 提取条件和操作符
        for (String str : conditions) {
            if (str.equals("AND") || str.equals("OR")) {
                operators.add(str);
            } else {
                conditionList.add(str);
            }
        }
        // 输出结果
        //condition
        for (String condition : conditionList) {
            Condition parsedCondition = parseCondition(condition);
            parsedConditionList.add(parsedCondition);
        }
        System.out.println("Parsed conditions: " + parsedConditionList);


        if (parsedConditionList.toArray().length == 0) {
            System.out.println("Error: Invalid condition.");
        }


        Iterator<Row> iterator = table.getRows().iterator();
        while (iterator.hasNext()) {
            Row row = iterator.next();
            List<Boolean> rowConditionResult = new ArrayList<>();
            for (Condition condition : parsedConditionList) {
                rowConditionResult.add(satisfiesCondition(row.getRowData(), condition));
                System.out.println("Condition: " + condition + ", Satisfied: " + satisfiesCondition(row.getRowData(), condition));
            }
            if (evaluateExpression(combineResultsAndOperators(rowConditionResult, operators))) {
                // 如果满足条件，则删除该行
                iterator.remove();
                System.out.println("Deleted row: " + row.getRowData());
            }
        }
        writeTableToFile(table, "." + File.separator + "databases" + File.separator + CmdType.getDbName() + File.separator + table.getTableName() + ".tab");
    }

    public static void writeTableToFile(Table table, String filePath) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            // 写入列名
            writer.write(String.join("\t", Table.getColumnNames()));
            writer.newLine();

            // 写入每一行的数据
            for (Row row : table.getRows()) {
                StringBuilder rowData = new StringBuilder();
                for (String columnName : Table.getColumnNames()) {
                    Object value = row.getRowData().get(columnName);
                    rowData.append(value != null ? value.toString() : "NULL").append("\t");
                }
                // 移除末尾的制表符并写入文件
                writer.write(rowData.toString().trim());
                writer.newLine();
            }
            System.out.println("Table data written to file: " + filePath);
        } catch (IOException e) {
            System.out.println("Error writing table data to file: " + e.getMessage());
        }
    }

    public static String combineResultsAndOperators(List<Boolean> rowConditionResult, List<String> operators) {
        StringBuilder combinedString = new StringBuilder();
        for (int i = 0; i < rowConditionResult.size(); i++) {
            combinedString.append(rowConditionResult.get(i) ? 'T' : 'F');
            if (i < operators.size()) {
                // 替换 AND 为 &
                if (operators.get(i).equals("AND")) {
                    combinedString.append(" & ");
                }
                // 替换 OR 为 |
                else if (operators.get(i).equals("OR")) {
                    combinedString.append(" | ");
                } else {
                    combinedString.append(" ").append(operators.get(i)).append(" ");
                }
            }
        }
        // 打印输出结果
        System.out.println("Combined string: " + combinedString.toString());
        return combinedString.toString();
    }


    public static boolean evaluateExpression(String expression) {
        Stack<Character> operatorStack = new Stack<>();
        Stack<Boolean> operandStack = new Stack<>();

        for (char c : expression.toCharArray()) {
            if (c == 'T' || c == 'F') {
                operandStack.push(c == 'T');
            } else if (c == '(') {
                operatorStack.push(c);
            } else if (c == ')') {
                while (operatorStack.peek() != '(') {
                    evaluate(operandStack, operatorStack);
                }
                operatorStack.pop(); // Pop the '('
            } else if (c == '&' || c == '|') {
                while (!operatorStack.isEmpty() && precedence(operatorStack.peek()) >= precedence(c)) {
                    evaluate(operandStack, operatorStack);
                }
                operatorStack.push(c);
            }
        }

        while (!operatorStack.isEmpty()) {
            evaluate(operandStack, operatorStack);
        }
        System.out.println("Final operand stack: " + operandStack);

        return operandStack.pop();
    }

    private static void evaluate(Stack<Boolean> operandStack, Stack<Character> operatorStack) {
        char operator = operatorStack.pop();
        boolean operand2 = operandStack.pop();
        boolean operand1 = operandStack.pop();
        if (operator == '&') {
            operandStack.push(operand1 && operand2);
        } else if (operator == '|') {
            operandStack.push(operand1 || operand2);
        }
    }

    private static int precedence(char operator) {
        if (operator == '&') {
            return 2;
        } else if (operator == '|') {
            return 1;
        }
        return 0; // '('
    }


    private static Condition parseCondition(String conditionString) {
        // Remove leading and trailing whitespaces
        conditionString = conditionString.trim();
        // Split by comparison operators
        String[] parts = conditionString.split("(?<=\\b(?:==|>|<|>=|<=|!=|LIKE)\\b)|(?=\\b(?:==|>|<|>=|<=|!=|LIKE)\\b)", 3);
        if (parts.length == 3) {
            String attributeName = parts[0].trim();
            String comparator = parts[1].trim(); // Extract the comparator directly
            String value = parts[2].trim(); // Extract the value directly

            // Create and return the condition object
            Condition condition = new Condition();
            condition.setAttributeName(attributeName);
            condition.setComparator(comparator);
            condition.setValue(value);
            return condition;
        }
        // Invalid condition
        return null;
    }

    private static boolean satisfiesCondition(Map<String, Object> row, Condition condition) {
        Object attributeValue = row.get(condition.getAttributeName());

        if (attributeValue == null) {
            System.out.println("Attribute value is null");
            return false;
        }

        // 处理条件值为字符串字面值或者 NULL 的情况
        if (condition.getValue() instanceof String || condition.getValue() == null) {
            // 如果属性值不是字符串，则转换为字符串进行比较
            if (!(attributeValue instanceof String)) {
                attributeValue = attributeValue.toString();
            }
            // 处理 NULL 值的情况
            if (condition.getValue() == null) {
                System.out.println("Condition value is null");
                return "NULL".equalsIgnoreCase((String) attributeValue);
            }
            // 去除条件值后面的分号
            String conditionValue = condition.getValue().toString().trim();
            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
            System.out.println("Attribute value: " + attributeValue);
            System.out.println("Condition value: " + conditionValue);
            return performStringComparison((String) attributeValue, conditionValue, condition.getComparator());
        }

        // 处理条件值为布尔字面值的情况
        if (condition.getValue() instanceof Boolean) {
            // 如果属性值不是布尔型，则无法满足条件
            if (!(attributeValue instanceof Boolean)) {
                System.out.println("Attribute value is not a boolean");
                return false;
            }
            // 去除条件值后面的分号
            String conditionValue = condition.getValue().toString().trim();
            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
            System.out.println("Attribute value: " + attributeValue);
            System.out.println("Condition value: " + conditionValue);
            return performBooleanComparison((Boolean) attributeValue, Boolean.parseBoolean(conditionValue), condition.getComparator());
        }

        // 处理条件值为整数字面值的情况
        if (condition.getValue() instanceof Integer) {
            // 如果属性值不是整数类型，则无法满足条件
            if (!(attributeValue instanceof Integer)) {
                System.out.println("Attribute value is not an integer");
                return false;
            }
            // 去除条件值后面的分号
            String conditionValue = condition.getValue().toString().trim();
            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
            System.out.println("Attribute value: " + attributeValue);
            System.out.println("Condition value: " + conditionValue);
            return performNumericComparison((Integer) attributeValue, Integer.parseInt(conditionValue), condition.getComparator());
        }

        // 处理条件值为浮点字面值的情况
        if (condition.getValue() instanceof Double || condition.getValue() instanceof Float) {
            // 如果属性值不是浮点数类型，则无法满足条件
            if (!(attributeValue instanceof Double) && !(attributeValue instanceof Float)) {
                System.out.println("Attribute value is not a float");
                return false;
            }
            // 去除条件值后面的分号
            String conditionValue = condition.getValue().toString().trim();
            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
            System.out.println("Attribute value: " + attributeValue);
            System.out.println("Condition value: " + conditionValue);
            try {
                double parsedAttributeValue = Double.parseDouble(attributeValue.toString());
                // 如果解析成功，则进行比较
                return performNumericComparison(parsedAttributeValue, Double.parseDouble(conditionValue), condition.getComparator());
            } catch (NumberFormatException e) {
                System.out.println("Error parsing attribute value to double: " + e.getMessage());
                return false;
            }
        }

        System.out.println("Unsupported condition value type");
        return false; // 不支持的条件值类型
    }

    // 执行字符串比较
    private static boolean performStringComparison(String attributeValue, String conditionValue, String comparator) {
        return switch (comparator) {
            case "==" -> attributeValue.equals(conditionValue);
            case ">" -> attributeValue.compareTo(conditionValue) > 0;
            case "<" -> attributeValue.compareTo(conditionValue) < 0;
            case "!=" -> !attributeValue.equals(conditionValue);
            case ">=" -> attributeValue.compareTo(conditionValue) >= 0;
            case "<=" -> attributeValue.compareTo(conditionValue) <= 0;
            case "LIKE" -> attributeValue.matches(conditionValue);
            default -> false; // 不支持的比较操作符
        };
    }

    // 执行布尔比较
    private static boolean performBooleanComparison(Boolean attributeValue, Boolean conditionValue, String comparator) {
        return switch (comparator) {
            case "==" -> attributeValue.equals(conditionValue);
            case "!=" -> !attributeValue.equals(conditionValue);
            default -> false; // 不支持的比较操作符
        };
    }

    // 执行数字比较
    private static <T extends Comparable<T>> boolean performNumericComparison(T attributeValue, T conditionValue, String comparator) {
        return switch (comparator) {
            case "==" -> attributeValue.compareTo(conditionValue) == 0;
            case ">" -> attributeValue.compareTo(conditionValue) > 0;
            case "<" -> attributeValue.compareTo(conditionValue) < 0;
            case "!=" -> attributeValue.compareTo(conditionValue) != 0;
            case ">=" -> attributeValue.compareTo(conditionValue) >= 0;
            case "<=" -> attributeValue.compareTo(conditionValue) <= 0;
            default -> false; // 不支持的比较操作符
        };
    }
}
